package org.janusproject.acl.encoding;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.janusproject.acl.ACLMessageContent;
import org.janusproject.acl.Performative;

/**
 * Helper used to parse and rebuild the decoded {@link ACLMessageContent}.
 * 
 * @author Mickael Adeline
 * @author Kevin Le Roy
 * @author Paul Talagrand
 */
public class StringACLCodecHelper {

	private static String PERFORMATIVE_PATTERN = "(\\()(.*)";
	private static int PERFORMATIVE_GROUP = 2;

	private static String SENDER_PATTERN = "(:sender)(\\s+)(\\()(\\s*)(agent-identifier)(\\s+)(:name)(\\s+)([a-zA-Z0-9_-]+)(\\s*)(\\))";
	private static int SENDER_GROUP = 9;
	
	private static String RECEIVER_PATTERN = "(:receiver)(\\s+)(\\()(\\s+)(set)(\\s+)(.*)(\\s*)(\\))";
	//private static int RECEIVER_GROUP = 7;
	
	private static String RECEIVER_ITEM_PATTERN = "(\\()(\\s*)(agent-identifier)(\\s+)(:name)(\\s+)([a-zA-Z0-9_-]+)(\\s*)(\\))";
	private static int RECEIVER_ITEM_GROUP = 7;
	
	private static String CONTENT_PATTERN = "(:content)(\\s+)(\\\")(.*)(\\\")(\\s*)";
	private static int CONTENT_GROUP = 4;
	
	private static String ENCODING_PATTERN = "(:encoding)(\\s+)(.*)(\\s*)";
	private static int ENCODING_GROUP = 3;
	
	private static String LANGUAGE_PATTERN = "(:language)(\\s+)(.*)(\\s*)";
	private static int LANGUAGE_GROUP = 3;
	
	private static String ONTOLOGY_PATTERN = "(:ontology)(\\s+)(.*)(\\s*)";
	private static int ONTOLOGY_GROUP = 3;
	
	private static String PROTOCOL_PATTERN = "(:protocol)(\\s+)(.*)(\\s*)";
	private static int PROTOCOL_GROUP = 3;
	
	private static String CONVERSATION_ID_PATTERN = "(:conversation-id)(\\s+)(.*)(\\s*)";
	private static int CONVERSATION_ID_GROUP = 3;
	
	private static String UUID_PATTERN = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
	
	public static boolean isPerformative( String str ){
		return doesPatternMatch( str, PERFORMATIVE_PATTERN );
	}
	
	public static int getPerformative( String str ){
		return Performative.valueOf( getMatch( str, PERFORMATIVE_PATTERN, PERFORMATIVE_GROUP ) ).ordinal();
	}
	
	public static boolean isSender( String str ){
		return doesPatternMatch( str, SENDER_PATTERN );
	}
	
	public static String getSender( String str ){
		return getMatch( str, SENDER_PATTERN, SENDER_GROUP );
	}

	public static boolean isReceiver( String str ){
		return doesPatternMatch( str, RECEIVER_PATTERN );
	}
	
	public static ArrayList<String> getReceiversList( String str ){
		return getMatches(str, RECEIVER_ITEM_PATTERN, RECEIVER_ITEM_GROUP);
	}
	
	public static boolean isContent( String str ){
		return doesPatternMatch( str, CONTENT_PATTERN );
	}
	
	public static String getContent( String str ){
		return getMatch( str, CONTENT_PATTERN, CONTENT_GROUP );
	}

	public static boolean isEncoding( String str ){
		return doesPatternMatch( str, ENCODING_PATTERN );
	}
	
	public static String getEncoding( String str ){
		return getMatch( str, ENCODING_PATTERN, ENCODING_GROUP );
	}
	
	public static boolean isLanguage( String str ){
		return doesPatternMatch( str, LANGUAGE_PATTERN );
	}
	
	public static String getLanguage( String str ){
		return getMatch( str, LANGUAGE_PATTERN, LANGUAGE_GROUP );
	}
	
	public static boolean isOntology( String str ){
		return doesPatternMatch( str, ONTOLOGY_PATTERN );
	}
	
	public static String getOntology( String str ){
		return getMatch( str, ONTOLOGY_PATTERN, ONTOLOGY_GROUP );
	}
	
	public static boolean isProtocol( String str ){
		return doesPatternMatch( str, PROTOCOL_PATTERN );
	}
	
	public static String getProtocol( String str ){
		return getMatch( str, PROTOCOL_PATTERN, PROTOCOL_GROUP );
	}
	
	public static boolean isConversationId( String str ){
		return doesPatternMatch( str, CONVERSATION_ID_PATTERN );
	}
	
	public static String getConversationId( String str ){
		return getMatch( str, CONVERSATION_ID_PATTERN, CONVERSATION_ID_GROUP );
	}
	
	public static boolean isUUID( String str ){
		return doesPatternMatch( str, UUID_PATTERN );
	}
	
	// Generic methods
	
	private static boolean doesPatternMatch( String str, String pattern ){
		return Pattern.compile( pattern ).matcher( str ).matches();
	}
	
	private static String getMatch( String str, String pattern, int group ){
		Matcher m = Pattern.compile( pattern ).matcher( str );
		m.find();
		String result = m.group( group );
		
		return (result == "null" ? null : result);
	}

	private static ArrayList<String> getMatches( String str, String pattern, int group ){
		Matcher m = Pattern.compile( pattern ).matcher( str );
		ArrayList<String> list = new ArrayList<String>();
		
		while (m.find()) {
		    list.add( m.group( group ) );
		}
		
		return list;
	}
}
